package com.zjtx.blog.service;

import com.zjtx.blog.utils.SecurityConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class RedisSecurityService {
    
    private static final Logger logger = LoggerFactory.getLogger(RedisSecurityService.class);
    
    @Autowired
    private StringRedisTemplate redisTemplate;
    
    // 配置参数
    @Value("${security.rate-limit.threshold:100}")
    private int rateLimitThreshold;
    
    @Value("${security.rate-limit.window:60}")
    private int rateLimitWindow;
    
    @Value("${security.blacklist.duration:86400}")
    private int blacklistDuration;

    /**
     * 检查IP是否在黑名单中
     */
    public boolean isIpBlacklisted(String ip) {
        String key = SecurityConstants.IP_BLACKLIST_PREFIX + ip;
        Boolean exists = redisTemplate.hasKey(key);
        return exists != null && exists;
    }
    
    /**
     * 将IP加入黑名单
     */
    public void blacklistIp(String ip, String reason) {
        String key = SecurityConstants.IP_BLACKLIST_PREFIX + ip;
        redisTemplate.opsForValue().set(key, reason, blacklistDuration, TimeUnit.SECONDS);
        logger.warn("IP {} blacklisted for reason: {}", ip, reason);
    }
    
    /**
     * 从黑名单中移除IP
     */
    public void removeIpFromBlacklist(String ip) {
        String key = SecurityConstants.IP_BLACKLIST_PREFIX + ip;
        redisTemplate.delete(key);
        logger.info("IP {} removed from blacklist", ip);
    }
    
    /**
     * 记录IP请求并检查是否超过频率限制
     */
    public boolean isRateLimited(String ip) {
        String key = SecurityConstants.IP_REQUEST_COUNT_PREFIX + ip;
        
        Long count = redisTemplate.opsForValue().increment(key, 1);
        
        if (count != null && count == 1) {
            redisTemplate.expire(key, rateLimitWindow, TimeUnit.SECONDS);
        }
        
        return count != null && count > rateLimitThreshold;
    }
    
    /**
     * 检查User-Agent是否为恶意的
     */
    public boolean isMaliciousUserAgent(String userAgent) {
        if (userAgent == null || userAgent.trim().isEmpty()) {
            return true; // 空User-Agent通常可疑
        }
        
        String key = SecurityConstants.MALICIOUS_UA_PREFIX + userAgent.hashCode();
        Boolean exists = redisTemplate.hasKey(key);
        
        if (exists == null || !exists) {
            boolean isMalicious = SecurityConstants.MALICIOUS_USER_AGENTS.stream()
                    .anyMatch(ua -> userAgent.toLowerCase().contains(ua.toLowerCase()));
            
            if (isMalicious) {
                redisTemplate.opsForValue().set(key, "1", 3600, TimeUnit.SECONDS);
            }
            
            return isMalicious;
        }
        
        return true;
    }
    
    /**
     * 检查路径是否为恶意路径
     */
    public boolean isMaliciousPath(String path) {
        return SecurityConstants.MALICIOUS_PATHS.stream()
                .anyMatch(pattern -> pattern.matcher(path).matches());
    }
    
    /**
     * 获取IP的请求计数
     */
    public Long getIpRequestCount(String ip) {
        String key = SecurityConstants.IP_REQUEST_COUNT_PREFIX + ip;
        String count = redisTemplate.opsForValue().get(key);
        return count != null ? Long.valueOf(count) : 0L;
    }
    
    /**
     * 获取黑名单中的所有IP
     */
    public Set<String> getBlacklistedIps() {
        Set<String> keys = redisTemplate.keys(SecurityConstants.IP_BLACKLIST_PREFIX + "*");
        if (keys == null) {
            return Collections.emptySet();
        }
        
        return keys.stream()
                .map(key -> key.substring(SecurityConstants.IP_BLACKLIST_PREFIX.length()))
                .collect(Collectors.toSet());
    }
    
    /**
     * 手动添加恶意User-Agent到缓存
     */
    public void addMaliciousUserAgent(String userAgent) {
        String key = SecurityConstants.MALICIOUS_UA_PREFIX + userAgent.hashCode();
        redisTemplate.opsForValue().set(key, "1", 86400, TimeUnit.SECONDS);
    }
}
